#ifndef UNIT_TEST_HPP
#define UNIT_TEST_HPP

#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)

#include <iostream>

#if !defined(TEST_IOSTREAM)
#define TEST_IOSTREAM std::cout
#endif

namespace unit_test {

inline const char*& test_name()
{
    static const char* name = nullptr;
    return name;
}

typedef void (*test_func_type)();

template <test_func_type func>
inline void run_test(const char* name)
{
    test_name() = name;
    func();
    TEST_IOSTREAM << name << " passed" << std::endl;
}

} // namespace unit_test

#define TEST_CASE(test) \
    unit_test::run_test<&test>(#test);

#define TEST_CHECK(expr) \
    if (!(expr)) { \
        TEST_IOSTREAM << unit_test::test_name() << "(" \
            << __FILE__ << ":" << __LINE__ << ") " \
            << "check '" << #expr << "' failed" << std::endl; \
    }

#endif // UNIT_TEST_HPP